#include <sstream>


#define GL_ASSERT( msg ) do                                                 \
        {                                                                   \
            GLenum glErr;                                                   \
            if ( GL_NO_ERROR != (glErr = glGetError( )) )                   \
            {                                                               \
                std::stringstream message;                                  \
                message << (msg) << gluErrorString( glErr );                \
                while ( GL_NO_ERROR != (glErr = glGetError( )) )            \
                {                                                           \
                    message << ", " << gluErrorString( glErr );             \
                }                                                           \
                message << ".";                                             \
                AfxMessageBox( message.str( ).c_str( ) );                   \
            }                                                               \
        } while(0)


#define AXIS_X          ( 1U )
#define AXIS_Y          ( AXIS_X<<1 )
#define AXIS_Z          ( AXIS_X<<2 )
#define ALL_AXES        ( (AXIS_X) | (AXIS_Y) | (AXIS_Z) )
// could be implemented as ~(AXIS_X | AXIS_Y | AXIS_Z) but that is less flexible
//#define FREE_CONTROL    (AXIS_X<<3)

#define ACT_ALONG_X( bitVector )              ( ((bitVector) & (AXIS_X)) != 0 )
#define ACT_ALONG_Y( bitVector )              ( ((bitVector) & (AXIS_Y)) != 0 )
#define ACT_ALONG_Z( bitVector )              ( ((bitVector) & (AXIS_Z)) != 0 )
#define FREE_CONTROL_IS_SELECTED( bitVector ) ( ((bitVector) & (ALL_AXES)) == 0 )

#define SELECT_AXIS_X( bitVector )          do { (bitVector) |= (AXIS_X); } while(0)
#define SELECT_AXIS_Y( bitVector )          do { (bitVector) |= (AXIS_Y); } while(0)
#define SELECT_AXIS_Z( bitVector )          do { (bitVector) |= (AXIS_Z); } while(0)
#define SELECT_FREE_CONTROL( bitVector )    do { (bitVector) &= ~(ALL_AXES); } while(0)
    
#define DESELECT_AXIS_X( bitVector )        do { (bitVector) &= ~(AXIS_X); } while(0)
#define DESELECT_AXIS_Y( bitVector )        do { (bitVector) &= ~(AXIS_Y); } while(0)
#define DESELECT_AXIS_Z( bitVector )        do { (bitVector) &= ~(AXIS_Z); } while(0)
#define DESELECT_FREE_CONTROL( bitVector )  do { SELECT_AXIS_X( bitVector ); } while(0)

#define TOGGLE_AXIS_X( bitVector )          do { (bitVector) ^= (AXIS_X); } while(0)
#define TOGGLE_AXIS_Y( bitVector )          do { (bitVector) ^= (AXIS_Y); } while(0)
#define TOGGLE_AXIS_Z( bitVector )          do { (bitVector) ^= (AXIS_Z); } while(0)
#define TOGGLE_FREE_CONTROL( bitVector )    \
    do { (bitVector) = FREE_CONTROL_IS_SELECTED( bitVector ) ? (bitVector) | (AXIS_X) : (bitVector) & ~(ALL_AXES); } while(0)

#define SELECT_AXIS_X_ONLY( bitVector )     do { (bitVector) = (((bitVector) | (AXIS_X)) & ~((AXIS_Y) | (AXIS_Z))); } while(0)
#define SELECT_AXIS_Y_ONLY( bitVector )     do { (bitVector) = (((bitVector) | (AXIS_Y)) & ~((AXIS_X) | (AXIS_Z))); } while(0)
#define SELECT_AXIS_Z_ONLY( bitVector )     do { (bitVector) = (((bitVector) | (AXIS_Z)) & ~((AXIS_X) | (AXIS_Y))); } while(0)
    




#if 0

namespace OpenGL {

typedef unsigned int StateBitVector;

const unsigned char ACTION_AXIS_X = 1;
const unsigned char ACTION_AXIS_Y = 1<<1;
const unsigned char ACTION_AXIS_Z = 1<<2;


bool xAxisIsActive(StateBitVector stateVector)
{
    return stateVector & ACTION_AXIS_X;
}


bool yAxisIsActive(StateBitVector stateVector)
{
    return stateVector & ACTION_AXIS_Y;
}


bool zAxisIsActive(StateBitVector stateVector)
{
    return stateVector & ACTION_AXIS_Z;
}

inline void glAssert(const char *msg)
{
    GLenum glErr;


    if( GL_NO_ERROR != (glErr = glGetError()) )
    {
        std::stringstream message;

        message << (msg) << gluErrorString(glErr);
        while( GL_NO_ERROR != (glErr = glGetError()) )
        {
            message << ", " << gluErrorString(glErr);
        }
        message << ".";
        AfxMessageBox(message.str().c_str());
    }
}

} // namespace OpenGL

#endif
